package com.wanqiu.ThreadPoolExecutorQueryDatabase.controller;

import com.wanqiu.ThreadPoolExecutorQueryDatabase.entity.UserInfo;
import com.wanqiu.ThreadPoolExecutorQueryDatabase.mapper.UserInfoMapper;
import com.wanqiu.ThreadPoolExecutorQueryDatabase.service.UserInfoService;
import com.wanqiu.ThreadPoolExecutorQueryDatabase.service.UserInfoServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author sunlele
 * @title: ThreadPoolQueryDBInfoController
 * @description: 线程池中线程查询数据库数据控制器
 * @date 2020/9/2810:34
 */
@RestController
@RequestMapping("/thread")
public class ThreadPoolQueryDBInfoController {
    @Autowired
    private UserInfoService userInfoService;
    @Autowired
    private UserInfoMapper userInfoMapper;

    static BlockingQueue queue = new LinkedBlockingQueue();
    static ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS, queue);

    /**
    * @description: 线程提交至线程池
    * @return success
    * @author sunlele
    * @date 2020/9/28 10:43
    */
    @RequestMapping("/queryDbInfo")
    public String getThreadQueryDBInfo(){
        //非线程调用查询数据库方法
        getInfo();
        System.out.println("线程池已启动....");
        //提交线程任务，执行查询数据库
        executor.submit(rn(userInfoMapper));
        return "success";
    }

    /**
    * @description: 线程任务
    * @author sunlele
    * @date 2020/9/28 10:42
    */
    public static Runnable rn(UserInfoMapper userInfoMapper){
        return  new Runnable() {
            @Override
            public void run() {
                try {
                    for ( int j = 0; j < 10; j++) {
                        System.out.println(Thread.currentThread().getName()+"回调内部第{"+(j+1)+"}次");
                        Thread.sleep(1000);
                        //调用查询方法，查询数据库
                        threadGetInfo(userInfoMapper);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    }

    /**
    * @description: 非线程查询数据库方法
    * @author sunlele
    * @date 2020/9/28 15:17
    */
    private void getInfo() {
        System.out.println("查询数据中...");
        List<UserInfo> userInfoList = userInfoService.query();
        if(userInfoList.size() > 0){
            System.out.println("数据大于0条...开始解析数据...");
            for (UserInfo userInfo : userInfoList){
                System.out.println(userInfo.toString());
            }
            System.out.println("数据解析完毕...");
        }else {
            System.out.println("数据小于0条...无需解析数据...");
        }
    }

    /**
     * @description: 线程查询数据库方法
     * 线程查询数据库时，service无法注入，mapper无法注入
     * 故.线程查询数据库时，service可以通过new实例，mapper则是需要在进入线程前注入，作为参数给到后面
     * 同理，线程查询整个执行逻辑中使用注入获得方法都需要提前在进入线程前给到
     * @param userInfoMapper
     * @author sunlele
     * @date 2020/9/28 15:17
     */
    private static void threadGetInfo(UserInfoMapper userInfoMapper) {
        System.out.println("查询数据中...");
        UserInfoService userInfoService = new UserInfoServiceImpl();
        List<UserInfo> userInfoList = userInfoService.threadQuery(userInfoMapper);
        if(userInfoList.size() > 0){
            System.out.println("数据大于0条...开始解析数据...");
            for (UserInfo userInfo : userInfoList){
                System.out.println(userInfo.toString());
            }
            System.out.println("数据解析完毕...");
        }else {
            System.out.println("数据小于0条...无需解析数据...");
        }
    }
}
